DBHandler
	parent_type = /Component
	numVerP = 1
	numVerM = 0
	numVerR = 12
	var
		DBConnection/DBC

		server = "localhost"
		port = 3306
		username = ""
		password = ""
		database = ""

	proc
		SetServer(s)
			server = s
		SetPort(p)
			port = p
		SetUser(u)
			username = u
		SetPass(p)
			password = p
		SetDB(d)
			database = d

		GetServer()
			return server
		GetPort()
			return port
		GetUser()
			return username
		GetPass()
			return password
		GetDB()
			return database

		GetDBI()
			return "dbi:mysql:[GetDB()]:[GetServer()]:[GetPort()]"

		SetName(n)
			DBC.name = n

		GetName()
			return DBC.name

		Connect(s, r, d, u, p)
			if(!s) s = GetServer()
			if(!r) r = GetPort()
			if(!d) d = GetDB()
			if(!u) u = GetUser()
			if(!p) p = GetPass()

			if(!DBC) DBC = new()
			DBC.Connect("dbi:mysql:[d]:[s]:[r]",u,p)
			if(!DBC.IsConnected()) return DBC.ErrorMsg()
			else return DBC.IsConnected()

		IsConnected()
			return DBC.IsConnected()

		NewQuery(sql as text|file)
			return new /Query(sql,src)

	New(s, r, d, u, p, c=1)
		world.log<<"NEW [src]"
		if(s) SetServer(s)
		if(r) SetPort(r)
		if(d) SetDB(d)
		if(u) SetUser(u)
		if(p) SetPass(p)
		if(c) Connect()
		SetName(GetDBI())


Query
	var/list/queries = list()
	var/DBHandler/DBH
	var/list/errmsg = list()
	var/index = 1
	proc
		GetRowData()
			var/DBQuery/Q = CurrentResultSet()
			return Q.GetRowData()

		NextResultSet()
			if(++index > queries.len)
				index = 1
			return index
		PrevResultSet()
			if(--index <= 0)
				index = queries.len
			return index
		RowCount()
			var/DBQuery.Q = CurrentResultSet()
			return Q.RowCount()
		NextRow()
			var/DBQuery.Q = CurrentResultSet()
			return Q.NextRow()
		CurrentResultSet()
			var/DBQuery/Q = queries[index]
			return Q
		ErrorMsg()
			var/ret = ""
			for(var/x in errmsg)
				ret += "[x]\n"
			return ret
		Execute()
			var/ret = TRUE
			var.cnt = 0
			//world.log<<"# of Queries: [queries.len]"
			for(var/DBQuery/q in queries)
				++cnt
				world.log<<"Q.SQL = [q.sql]"
				if(!q.Execute())
					//world.log<<"FAILED"
					errmsg.Add("Statement [cnt] - [q.ErrorMsg()]")
					ret = FALSE
				else
					//world.log<<"SUCCESS"
			//world.log<<"RETURNING"
			return ret

	New(sql as text|file, DBHandler/d)
		if(d)
			DBH = d
		world.log<<"NEW [src]"
		var/raw
		if(findtext(sql,".sql"))
		//if(isfile(sql))
			//world.log<<"FILE FOUND"
			raw = file2text(file(sql))
		else
			raw = sql
		var/list/l = dd_text2list(raw,";")
		//world.log<<"Beginning parse out of [raw]"
		for(var/line in l)
			if(length(line) <= 0) continue
			var/DBQuery/q = DBH.DBC.NewQuery(line)
			queries.Add(q)
			if(!dd_debugger.extraControlPanelObjects.len) dd_debugger.extraControlPanelObjects = list()
			dd_debugger.extraControlPanelObjects.Add(q)


DBConnection
	var/name


/*
CONCEPTS

	DBHandler extends the DBController functionality
	Games should have 1 GameDBC which is used by the software, no end-user manipulation
	Clients should have their own DBHandler, allowing client-based permission sets

	Prime example of why have client-based DBCs: allow developers / admins more direct control over
	a database, perhaps implement a developer DB that mirrors the live, etc.
*/